<?php
/**
 * Created by PhpStorm.
 * User: wodrow
 * Date: 18-6-12
 * Time: 上午11:04
 */

namespace common\components\big_data;


use common\components\tools\Tools;
use common\models\BaiRongValidateLog;
use wodrow\yii\rest\ApiException;
use yii\base\ErrorException;
use yii\httpclient\Client;
use yii\web\Response;

class BaiRong extends BigData implements Api
{
    public $api_user_account;
    public $api_user_password;
    public $api_user_api_code;
    public $api_login_url;
    public $web_user_account;
    public $web_user_password;
    public $web_user_api_code;
    public $web_login_url;
    public $need_strategys;

    protected $_widghtInfo = [
        'w' => 0,
        'd' => '',
        'str' => '',
    ]; // 权重

    /**
     * @var BaiRongValidateLog $validateLog
     */
    public $validateLog;

    /**
     * @param $name
     * @param $ID_no
     * @param $mobile
     * @param int $is_log_to_array
     * @param string $other_data
     * @param int $import_type
     * @return array
     * @throws ErrorException
     */
    public function check($name, $ID_no, $mobile, $is_log_to_array = 1, $other_data = '', $import_type = BaiRongValidateLog::IMPORT_TYPE_DEFAULT, $re_check = 0)
    {
        $r = ['validate_log' => []];
        $user = [
            'id' => $ID_no,
            'name' => $name,
            'cell' => $mobile,
//            'cell' => [$mobile],
        ];
        $cache_key = $name.$ID_no.$mobile;
        if (\Yii::$app->cache->get($cache_key)){
            throw new ApiException(201905171448, "并发重复提交了用户");
        }
        \Yii::$app->cache->set($cache_key, 1, 300);
        $r['check_user'] = $user;
        foreach ($this->need_strategys as $k => $v){
            $this->validateLog = BaiRongValidateLog::findOne([
                'strategy_type' => $k,
                'req_name' => $name,
                'req_idcard' => $ID_no,
                'req_mobile' => $mobile,
            ]);
            if (!$this->validateLog) {
                $this->validateLog = new BaiRongValidateLog();
                $this->validateLog->strategy_type = $k;
                $this->validateLog->req_name = $name;
                $this->validateLog->req_idcard = $ID_no;
                $this->validateLog->req_mobile = $mobile;
                $this->validateLog->other_data = $other_data;
                $this->validateLog->import_type = $import_type;
            }
            if (!in_array($this->validateLog->resp_code, ['00', '100002', '600000']) || $re_check){
                $resp = $this->validate($v, $user);
                $resp_content_json = json_decode($resp->content);
                $this->validateLog->resp_code = $resp_content_json->code;
                if (isset($resp_content_json->swift_number))$this->validateLog->resp_swift_number = $resp_content_json->swift_number;
                $this->validateLog->resp_data_for_api_send = $resp->content;
                $this->validateLog->created_at = time();
                if (!$this->validateLog->save()){
                    throw new ErrorException("validateLog保存失败".var_export($this->validateLog->errors, true));
                }
            }
            $this->validateLog->api_send_post_data = json_decode($this->validateLog->api_send_post_data, true, 512);
            $this->validateLog->resp_data_for_api_send = json_decode($this->validateLog->resp_data_for_api_send, true, 512);
            if ($is_log_to_array){
                $r['validate_log'][] = $this->validateLog->toArray();
            }else{
                $r['validate_log'][] = $this->validateLog;
            }
        }
        \Yii::$app->cache->delete($cache_key);
        return $r;
    }

    /**
     * @param $apiname
     * @param $user
     * @return \yii\httpclient\Response
     */
    public function validate($apiname, $user)
    {
        $login_data = $this->getApiLoginData();
        $token = $login_data['tokenid'];
        $data = $user;
        $strategy = $this->selectStrategy($apiname);
        $strategy_key = $strategy['key'];
        $url = $strategy['url'];
        $data[$strategy_key] = $apiname;
        $json_data = json_encode($data);
        $check_code = md5($json_data.md5($login_data['apiCode'] . $token));
        $post_data = [
            'tokenid' => $token,
            'interCommand' => '1000',
            'apiCode' => $login_data['apiCode'],
            'jsonData' => $json_data,
            'checkCode' => $check_code,
        ];
        $this->validateLog->api_send_post_data = json_encode($post_data);
        $client = new Client();
        $r = $client->post($url, $post_data)->send();
        return $r;
    }

    /**
     * api用户登陆
     * @return mixed
     * @throws ErrorException
     */
    public function getApiLoginData()
    {
        $cache_key = $this->api_user_account.$this->api_user_password.$this->api_user_api_code.'bairong_api_token_id';
//        \Yii::$app->cache->delete($cache_key);
        $token = \Yii::$app->cache->get($cache_key);
        if (!$token){
            $username = $this->api_user_account;
            $password = $this->api_user_password;
            $apicode = $this->api_user_api_code;
            $url = $this->api_login_url;
            $postData = array(
                "userName" => $username,
                "password" => $password,
                "apiCode" => $apicode,
            );
            $client = new Client();
            $r = $client->post($url, $postData)->send();
            $c = json_decode($r->content, true, 512);
            if ($c['code'] == '00'){
                $token = $c['tokenid'];
                \Yii::$app->cache->set($cache_key, $token, 1800);
            }else{
                throw new ErrorException('api没有获取到token'.var_export($c, true));
            }
        }
        $data['tokenid'] = $token;
        $data['apiCode'] = $this->api_user_api_code;
        return $data;
    }

    /**
     * web用户登陆
     * @return mixed
     * @throws ErrorException
     */
    public function getWebLoginData()
    {
        $cache_key = $this->web_user_account.$this->web_user_password.$this->web_user_api_code.'bairong_web_token_id';
//        \Yii::$app->cache->delete($cache_key);
        $token = \Yii::$app->cache->get($cache_key);
        if (!$token){
            $username = $this->web_user_account;
            $password = $this->web_user_password;
            $url = $this->web_login_url;
            $postData = array(
                "username" => $username,
                "password" => $password,
            );
            $client = new Client();
            $r = $client->post($url, $postData, [
                'Content-Type' => "application/x-www-form-urlencoded",
            ])->send();
            $c = json_decode($r->content, true, 512);
            if ($c['code'] == '000000'){
                $token = $c['data'];
                \Yii::$app->cache->set($cache_key, $token, 1800);
            }else{
                throw new ErrorException('web没有获取到token'.var_export($c, true));
            }
        }
        $data['tokenid'] = $token;
        $data['apiCode'] = $this->web_user_api_code;
        return $data;
    }

    /**
     * detail_list 策略格式化返回
     * @param $data
     */
    public function formatDetailList($data, $is_array = 0)
    {
        if (!$is_array) $data = json_decode($data, true, 512);
        $r = '[策略引擎]';
        if (isset($data['Rule_final_weight'])){
            $w = $data['Rule_final_weight'];
        }else{
            $w = 0;
        }
//        $w = $data['Rule_final_weight'];
        if (isset($data['Rule_final_decision'])){
            $d = $data['Rule_final_decision'];
        }else{
            $d = '';
        }
        if ($w >= $this->_widghtInfo['w']){
            $this->_widghtInfo['w'] = $w;
            $this->_widghtInfo['d'] = $d;
            $this->_widghtInfo['str'] = self::$final_decision_status_value[$d]."({$w}), ";
        }
//        $r .= self::$final_decision_status_value[$d]."({$w}), ";
        $rule_name = [];
        foreach ($data as $k => $v){
            if (strpos($k, 'Rule_name_')!==false){
                $rule_name[] = $v;
            }
        }
        $r .= Tools::arr2str($rule_name);
        return $r;
    }

    /**
     * person_recognition 自然人识别格式化返回 [兼容历史问题]
     * @param $data
     */
    public function formatPersionRecognitionOld($data, $is_array = 0)
    {
        if (!$is_array) $data = json_decode($data, true, 512);
        $r = "[自然人识别]";
        if (!isset($data['flag'])){
            throw new ErrorException($r.":".var_export($data, true).var_export($_REQUEST, true));
        }
        if (!$data['flag']['flag_badinfo']){
            return $r."正常";
        }
        if ($data['product']['ztCheckresult']){
            $r .= "zt ";
        }
        if ($data['product']['sdCheckresult']){
            $r .= "sd ";
        }
        if ($data['product']['xdCheckresult']){
            $r .= "xd ";
        }
        /*if ($data['product']['wfxwCheckresult']){
            $r .= "wfxw ";
        }
        if ($data['product']['checkCount2']){
            $r .= "次数"." {$data['product']['checkCount2']}次:";
        }*/
        if ($data['product']['item']){
            $item = $data['product']['item'];
            $type_dist = self::$case_type_dist;
            if (isset($type_dist[$item['caseTypeCode']])){
                $x = $type_dist[$item['caseTypeCode']];
            }else{
                $x = "其他";
            }
            $r .= "最近时间{$item['caseTime']}". $x."({$item['caseTypeCode']})".";";
        }
        return $r;
    }

    /**
     * person_recognition 自然人识别格式化返回
     * @param $data
     */
    public function formatPersionRecognition($data, $is_array = 0)
    {
        if (!$is_array) $data = json_decode($data, true, 512);
//        echo "<pre>";var_dump($data);exit;
        $r = "[自然人识别]";
        if (!isset($data['Flag'])){
            throw new ErrorException($r.":".var_export($data, true)." \r ".var_export($_REQUEST, true));
        }
        if (isset($data['Flag']['badinfo'])&&!$data['Flag']['badinfo']){
            $r = $r."正常";
        }
        if (isset($data['BadInfo']['ztCheckresult'])&&$data['BadInfo']['ztCheckresult']){
            $r .= "zt ";
        }
        if (isset($data['BadInfo']['sdCheckresult'])&&$data['BadInfo']['sdCheckresult']){
            $r .= "sd ";
        }
        if (isset($data['BadInfo']['xdCheckresult'])&&$data['BadInfo']['xdCheckresult']){
            $r .= "xd ";
        }
        /*if (isset($data['BadInfo']['wfxwCheckresult'])&&$data['BadInfo']['wfxwCheckresult']){
            $r .= "wfxw ";
        }
        if (isset($data['BadInfo']['checkCount2'])){
            $r .= "次数"." {$data['BadInfo']['checkCount2']}次 ";
        }*/
        if (isset($data['BadInfo']['item'])){
            $item = $data['BadInfo']['item'];
            $type_dist = self::$case_type_dist;
            if (isset($item['caseTypeCode'])){
                if (isset($type_dist[$item['caseTypeCode']])){
                    $x = $type_dist[$item['caseTypeCode']];
                }else{
                    $x = "其他";
                }
                $r .= "最近时间{$item['caseTime']}". $x."({$item['caseTypeCode']})".";";
            }
        }
        if (isset($data['InfoVerification']['hit_rules'])){
            foreach ($data['InfoVerification']['hit_rules'] as $k => $v){
                foreach ($v as $k1 => $v1){
                    $r .= "{$v1['name_rule']} ";
                }
            }
        }
        if ($data['Flag']['infoverification']){
            if (isset($data['InfoVerification']['final_weight'])){
                $w = $data['InfoVerification']['final_weight'];
            }else{
                $w = 0;
            }
            if (isset($data['InfoVerification']['final_decision'])){
                $d = $data['InfoVerification']['final_decision'];
            }else{
                $d = '';
            }
            if ($w >= $this->_widghtInfo['w']){
                $this->_widghtInfo['w'] = $w;
                $this->_widghtInfo['d'] = $d;
                $this->_widghtInfo['str'] = self::$final_decision_status_value[$d]."({$w}), ";
            }
//            $r .= self::$final_decision_status_value[$d]."({$w}), ";
        }
        return $r;
    }

    public function optimizeShowStr($str)
    {
        $str = $this->_widghtInfo['str'].$str;
        return $str;
    }

    /**
     * @param $strategy_str
     * @return array
     * @throws ErrorException
     */
    public function selectStrategy($strategy_str)
    {
        $pre = substr($strategy_str, 0, 3);
        switch ($pre){
            case 'DTV':
                $key = 'conf_id';
                $url = 'https://api.100credit.cn/infoverify/v1/info_verify';
                $report_url_pre = 'https://infocheck.100credit.com/#/userReport/';
                break;
            case 'MCP':
                $key = 'conf_id';
                $url = 'https://api.100credit.cn/infoverify/v1/info_verify';
                $report_url_pre = 'https://infocheck.100credit.com/#/userReport/';
                break;
            case 'STR':
                $key = 'strategy_id';
                $url = 'https://api.100credit.cn/strategyApi/v1/hxQuery';
                $report_url_pre = 'https://apiservice.100credit.com/v/#/userReport/';
                break;
            default:
                throw new ErrorException("没有可选的引擎前缀");
                break;
        }
        $strategy['key'] = $key;
        $strategy['url'] = $url;
        $strategy['report_url_pre'] = $report_url_pre;
        return $strategy;
    }

    const FINAL_DECISION_ACCEPT = 'Accept'; // 通过 "final_weight"="0"
    const FINAL_DECISION_REJECT = 'Reject'; // 拒绝 "final_weight">="80"
    const FINAL_DECISION_REVIEW = 'Review'; // 复议 "0"<"final_weight"<"80"
    const FINAL_DECISION_NO = ''; // 无建议

    public static $final_decision_status_value = [
        self::FINAL_DECISION_REJECT => '建议拒绝',
        self::FINAL_DECISION_REVIEW => '复议',
        self::FINAL_DECISION_ACCEPT => '建议通过',
        self::FINAL_DECISION_NO => '无建议',
    ];

    public static $case_type_dist = [
        '1010000' => "背叛、分裂国家案",
        '1020000' => "投敌叛变案",
        '1030000' => "非法提供秘密情报案",
        '2010000' => "危害社会公共安全案",
        '2020000' => "破坏交通运输公共设施案",
        '2030000' => "实施恐怖案",
        '2040000' => "非法枪支弹药爆炸案",
        '2050000' => "违反枪支弹药管理案",
        '2060000' => "重大安全责任事故案",
        '3010000' => "生产、销售伪劣商品案",
        '3020000' => "走私案",
        '3030000' => "妨害对公司、企业的管理秩序案",
        '3040000' => "破坏金融管理秩序案",
        '3050000' => "金融诈骗案",
        '3060000' => "危害税收征管案",
        '3070000' => "侵犯知识产权案",
        '3080000' => "扰乱市场秩序案",
        '3090000' => "非法经营案",
        '4010000' => "侵犯人身权利案",
        '4020000' => "破坏民族平等、宗教信仰案",
        '4030000' => "侵犯民主权利案",
        '4040000' => "出售、非法提供公民个人信息案",
        '4050000' => "妨碍婚姻家庭权利案",
        '5010000' => "侵犯财产案",
        '6010000' => "扰乱公共秩序案",
        '6020000' => "妨害司法案",
        '6030000' => "妨害国（边）境管理案",
        '6040000' => "妨害文物管理案",
        '6050000' => "危害公共卫生案",
        '6060000' => "破坏环境资源保护案",
        '6070000' => "涉毒案",
        '6100000' => "卖淫、传播淫秽物品案",
        '7010000' => "危害国防利益案",
        '8010000' => "贪污贿赂案",
        '9010000' => "渎职案",
        '10010000' => "军人违反职责案",
        '其他' => "其他",
    ];
}